package com.idanchuang.spi.config;

import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * @author yjy
 * @date 2019/11/8 10:26
 **/
public interface IConfig {

    /**
     * @return 所有配置的key集合
     */
    Set<String> getKeys();

    /**
     * @return 所有配置集合
     */
    Map<String, Object> getAll();

    /**
     * 获取并解析为String
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    String getString(String key, String defaultValue);

    /**
     * 获取配置并解析为Integer
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Integer getInteger(String key, Integer defaultValue);

    /**
     * 获取配置并解析为Short
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Short getShort(String key, Short defaultValue);

    /**
     * 获取配置并解析为Byte
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Byte getByte(String key, Byte defaultValue);

    /**
     * 获取并解析为Long
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Long getLong(String key, Long defaultValue);

    /**
     * 获取并解析为Float
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Float getFloat(String key, Float defaultValue);

    /**
     * 获取并解析为Double
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Double getDouble(String key, Double defaultValue);

    /**
     * 获取并解析为Boolean
     * @param key 键
     * @param defaultValue 默认值
     * @return 值, 不存在时返回默认值
     */
    Boolean getBoolean(String key, Boolean defaultValue);

    /**
     * 获取并解析为String数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    String[] getStringArray(String key, String... defaultValues);

    /**
     * 获取并解析为Integer数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Integer[] getIntegerArray(String key, Integer... defaultValues);

    /**
     * 获取并解析为Integer数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Short[] getShortArray(String key, Short... defaultValues);

    /**
     * 获取并解析为Byte数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Byte[] getShortArray(String key, Byte... defaultValues);

    /**
     * 获取并解析为Long数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Long[] getLongArray(String key, Long... defaultValues);

    /**
     * 获取并解析为Double数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Double[] getDoubleArray(String key, Double... defaultValues);

    /**
     * 获取并解析为Float数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Float[] getFloatArray(String key, Float... defaultValues);

    /**
     * 获取并解析为Boolean数组
     * @param key 键
     * @param defaultValues 默认值
     * @return 值, 不存在时返回默认值
     */
    Boolean[] getBooleanArray(String key, Boolean... defaultValues);


    /**
     * 获取配置并解析为Date (支持自动识别格式为: yyyy-MM-dd HH:mm:ss / yyyy-MM-dd HH:mm:ss.SSS / yyyy-MM-dd)
     *
     * @param key          键
     * @param defaultValue 配置不存在时返回的默认值
     * @return 配置值
     */
    Date getDate(String key, Date defaultValue);

    /**
     * 获取配置并解析为Date
     *
     * @param key          键
     * @param format       指定格式化格式
     * @param defaultValue 配置不存在时返回的默认值
     * @return 配置值
     */
    Date getDate(String key, String format, Date defaultValue);

    /**
     * 获取配置并解析为Date
     *
     * @param key          键
     * @param format       指定格式化格式
     * @param locale       地区
     * @param defaultValue 配置不存在时返回的默认值
     * @return 配置值
     */
    Date getDate(String key, String format, Locale locale, Date defaultValue);

    /**
     * 获取配置并解析为map
     * @param key 键
     * @return 配置值
     */
    Map<String, Object> getMap(String key);

    /**
     * 添加一个配置变动监听器
     * @param listener 触发逻辑
     */
    void addChangeListener(ConfigChangeListener listener);

    /**
     * 添加一个配置变动监听器
     * @param listener 触发逻辑
     */
    default void addChangeListener(ConfigChangeWithKeysListener listener) {
        // default
        throw new UnsupportedOperationException();
    }

}
